package cn.fanqinghong.ymcc.service.impl;

import cn.fanqinghong.ymcc.constants.CommonConstants;
import cn.fanqinghong.ymcc.constants.RegisterDto;
import cn.fanqinghong.ymcc.constants.YmccError;
import cn.fanqinghong.ymcc.domain.*;
import cn.fanqinghong.ymcc.dto.RedisRegisterDto;
import cn.fanqinghong.ymcc.feignClient.BlacklistFeignClient;
import cn.fanqinghong.ymcc.feignClient.LoginFeignClient;
import cn.fanqinghong.ymcc.feignClient.MessageSmsFeignClient;
import cn.fanqinghong.ymcc.mapper.UserMapper;
import cn.fanqinghong.ymcc.result.JSONResult;
import cn.fanqinghong.ymcc.service.IUserAccountService;
import cn.fanqinghong.ymcc.service.IUserBaseInfoService;
import cn.fanqinghong.ymcc.service.IUserService;
import cn.fanqinghong.ymcc.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author superman.fan
 * @since 2022-07-15
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private LoginFeignClient loginFeignClient;
    @Autowired
    private IUserAccountService userAccountService;
    @Autowired
    private IUserBaseInfoService userBaseInfoService;
    @Autowired
    private BlacklistFeignClient blacklistFeignClient;
    @Autowired
    private MessageSmsFeignClient messageSmsFeignClient;
    /**
     * 通过电话号码获取信息
     * @param phone
     * @return
     */
    @Override
    public User selectByPhone(String phone) {
        Wrapper<User> tWrapper = new EntityWrapper<>();
        tWrapper.eq("phone",phone);
        return selectOne(tWrapper);
    }

    /**
     * 注册
     * @param dto
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class) //发起事务
    public void register(RegisterDto dto) {
        Object data = blacklistFeignClient.getPhone(dto.getMobile()).getData();
        System.out.println(data);
        AssertUtil.isNull(data,YmccError.PHONE_IS_IN_BLACKLIST.getMessage());
        String key =  String.format(CommonConstants.REGISTER_PHONE_PREFIX,dto.getMobile());
        //验证码是否正确
        Object o = redisTemplate.opsForValue().get(key);
        AssertUtil.isNotNull(o, YmccError.USER_SMS_IS_EMPTY.getMessage());
        RedisRegisterDto RedisRegisterDto = (RedisRegisterDto) o;
        //判断输入的验证码，何redis中验证码是否相等
        AssertUtil.isEquals(RedisRegisterDto.getCode(),dto.getSmsCode(),YmccError.USER_SMS_IS_NOT_EQUEAL.getMessage());
        //手机号是否被注册
        User user = selectByPhone(dto.getMobile());
        if(user != null) {
            AssertUtil.isTrue(user.getBlackStatic() == 0, YmccError.PHONE_IS_IN_BLACKLIST.getMessage());
        }
        AssertUtil.isNull(user,YmccError.USER_IS_NOT_NULL.getMessage());

        //保存登录信息
        JSONResult jsonResult = saveLogin(dto);

        //判断保存成功
        AssertUtil.isTrue(jsonResult.isSuccess(),YmccError.LOGIN_SAVE_FAIL.getMessage());
        Long loginId = Long.valueOf(jsonResult.getData().toString());
        Date date = new Date();
        Long time = date.getTime();

        //保存user相关的表
        user = saveUser(loginId, dto, time);
        AssertUtil.isNotNull(user.getId(),YmccError.USER_ID_IS_NULL.getMessage());
        //保存User_base_info表
        saveUserBaseInfo(user,time,dto);
        AssertUtil.isNotNull(user.getId(),YmccError.USERBASEINFO_ID_IS_NULL.getMessage());


        //保存user_account表
        saveUserAccount(user,time);
        AssertUtil.isNotNull(user.getId(),YmccError.USERACCOUNT_ID_IS_NULL.getMessage());

        //设置userId给sms表
        //根据手机号获取sms表中的数据
        Object smsData = messageSmsFeignClient.get(user.getPhone()).getData();
        List<MessageSms> messageSms = JSONArray.parseArray(JSON.toJSON(smsData).toString(), MessageSms.class);
        //遍历设置userId
        for (MessageSms sms : messageSms){
            sms.setUserId(user.getId());
        }
        messageSmsFeignClient.batch(messageSms);

    }

    private void saveUserAccount(User user,Long time) {
        UserAccount userAccount = new UserAccount();
        userAccount.setId(user.getId());
        userAccount.setCreateTime(time);
        userAccountService.insert(userAccount);
    }

    /**
     * 保存User_base_info表
     * @param user
     * @param time
     * @param dto
     */
    private void saveUserBaseInfo(User user,Long time,RegisterDto dto) {
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setId(user.getId());
        userBaseInfo.setCreateTime(time);
        userBaseInfo.setRegChannel(dto.getRegChannel());
        userBaseInfoService.insert(userBaseInfo);
    }

    /**
     * 保存user表
     * @param loginId
     * @param dto
     * @param time
     * @return
     */
    private User saveUser(Long loginId, RegisterDto dto, Long time) {
        User user = new User();
        user.setLoginId(loginId);
        user.setCreateTime(time);
        user.setPhone(dto.getMobile());
        user.setNickName(dto.getMobile());
        user.setBlackStatic(0);
        insert(user);
        return user;
    }

    /**
     * 保存登录信息
     */
    private JSONResult saveLogin(RegisterDto dto) {
        Login login = new Login();
        login.setType(Login.TYPE_USER);
        login.setUsername(dto.getMobile());
        login.setPassword(dto.getPassword());
        return loginFeignClient.save(login);
    }
}
